<template>
  <div class="multistep-form">
    <!-- Navigation -->
    <div v-if="showNavigation" class="navigation" :class="navigationPosition">
      <div v-for="(step, index) in effectiveSteps"
           :key="index"
           class="step-indicator"
           :class="{ active: index === currentStep }">
        <div class="step-number">{{ index + 1 }}</div>
        <div class="step-info">
          <div class="step-title">{{ step.title }}</div>
          <div v-if="step.description" class="step-description">{{ step.description }}</div>
        </div>
      </div>
    </div>

    <!-- Steps Content -->
    <div class="steps-wrapper">
      <transition :name="transitionName" mode="out-in">
        <div :key="currentStep" class="step-content">
          <slot :name="`step-${currentStep}`"
                :formData="formData"
                :step="effectiveSteps[currentStep]">
            {{ effectiveSteps[currentStep]?.content }}
          </slot>
        </div>
      </transition>
    </div>

    <!-- Navigation Controls -->
    <div class="form-controls">
      <button v-if="currentStep > 0"
              @click="handlePrev"
              :disabled="disablePrev">
        {{ prevButtonText }}
      </button>

      <button v-if="currentStep < effectiveStepCount - 1"
              @click="handleNext"
              :disabled="disableNext">
        {{ nextButtonText }}
      </button>

      <button v-else
              @click="handleFinish"
              :disabled="disableNext">
        {{ finishButtonText }}
      </button>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, computed, watch, onMounted } from 'vue'

const props = defineProps({
  steps: { type: Array, default: () => [] },
  currentStep: { type: Number, default: 0 },
  stepCount: Number,
  showNavigation: { type: Boolean, default: true },
  navigationPosition: { type: String, default: 'top', validator: v => ['top', 'bottom'].includes(v) },
  prevButtonText: { type: String, default: '上一步' },
  nextButtonText: { type: String, default: '下一步' },
  finishButtonText: { type: String, default: '完成' },
  disablePrev: { type: Boolean, default: false },
  disableNext: { type: Boolean, default: false },
  validateBeforeNext: { type: Boolean, default: true },
  submitUrl: { type: String, default: '' },
  method: { type: String, default: 'POST' },
  transition: { type: String, default: 'fade' },
  initialForm: {
    type: Object,
    default: () => ({})
  }
})

const emit = defineEmits([
  'update:currentStep',
  'prev',
  'next',
  'finish',
  'stepChange',
  'error'
])

// Reactive state
const formData = ref(props.initialForm)
const transitionName = ref(props.transition)

// Computed properties
const effectiveStepCount = computed(() =>
    props.stepCount || props.steps.length || 0
)

const effectiveSteps = computed(() => {
  if (props.steps.length > 0) return props.steps
  return Array.from({ length: effectiveStepCount.value }, (_, i) => ({
    title: `步骤 ${i + 1}`,
    content: ''
  }))
})

// Watch for step changes to persist data
watch(() => props.currentStep, (newStep, oldStep) => {
  emit('stepChange', { from: oldStep, to: newStep })
})

// Watch for initialForm changes
watch(() => props.initialForm, (newValue) => {
  formData.value = { ...newValue }
}, { deep: true })

// Initialize form data
onMounted(() => {
  effectiveSteps.value.forEach((_, index) => {
    if (!formData[index]) formData[index] = reactive({})
  })
})

// Navigation handlers
function handlePrev() {
  const prevStep = props.currentStep - 1
  if (prevStep >= 0) {
    emit('update:currentStep', prevStep)
    emit('prev')
  }
}

async function handleNext() {
  if (props.validateBeforeNext) {
    try {
      await emit('next', {
        currentStep: props.currentStep,
        data: formData[props.currentStep]
      })
      moveToNextStep()
    } catch (error) {
      emit('error', error)
    }
  } else {
    moveToNextStep()
  }
}

function moveToNextStep() {
  const nextStep = props.currentStep + 1
  if (nextStep < effectiveStepCount.value) {
    emit('update:currentStep', nextStep)
    emit('next')
  }
}

function handleFinish() {
  emit('finish', formData)
  if (props.submitUrl) {
    submitForm()
  }
}

async function submitForm() {
  try {
    const response = await fetch(props.submitUrl, {
      method: props.method,
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(formData)
    })
    if (!response.ok) throw new Error('提交失败')
  } catch (error) {
    emit('error', error)
  }
}
</script>

<style scoped>
.multistep-form {
  display: flex;
  flex-direction: column;
  gap: 2rem;
}

.navigation {
  display: flex;
  justify-content: space-between;
  padding: 1rem;
  background: #f5f5f5;
}

.navigation.bottom {
  order: 2;
}

.step-indicator {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 1rem;
  opacity: 0.5;
  transition: opacity 0.3s;
}

.step-indicator.active {
  opacity: 1;
}

.step-number {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: #ddd;
  display: flex;
  align-items: center;
  justify-content: center;
}

.step-info {
  display: none;
}

@media (min-width: 768px) {
  .step-info {
    display: block;
  }
}

.steps-wrapper {
  position: relative;
  min-height: 300px;
}

.step-content {
  position: absolute;
  width: 100%;
  padding: 1rem;
}

/* Transition effects */
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

.slide-left-enter-active,
.slide-left-leave-active {
  transition: transform 0.3s ease;
}

.slide-left-enter-from {
  transform: translateX(100%);
}

.slide-left-leave-to {
  transform: translateX(-100%);
}

.form-controls {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem;
  background: #f5f5f5;
}
</style>